package com.celeritymq.client;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.celeritymq.utils.ObjectUtil;

public class CelerityClientImpl implements CelerityClient {
	SocketChannel sc;
	volatile boolean connected;
	Selector selector;

	public CelerityClientImpl() throws IOException {
		sc = SocketChannel.open();
		sc.configureBlocking(false);
		sc.socket().setReuseAddress(true);
	}

	private void start() throws UnknownHostException, IOException {
		selector = Selector.open();
		sc.register(selector, SelectionKey.OP_CONNECT);
		sc.connect(new InetSocketAddress("127.0.0.1", 9999));
		System.out.println("connected: " + sc.isConnected());
		System.out.println("connected2: " + sc.isConnected());
		while (true) {
			int num = selector.select();
			if (num < 1) {
				System.out.println("num<1");
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				continue;
			}
			Set<SelectionKey> keys = selector.selectedKeys();
			Iterator<SelectionKey> it = keys.iterator();
			while (it.hasNext()) {
				SelectionKey key = it.next();
				if (key.isValid() && key.isConnectable()) {
					System.out.println("connetable");
					// sc.connect(new
					// InetSocketAddress(InetAddress.getLocalHost(),9999));
					// System.out.println("connected: "+ sc.isConnected());
					sc.finishConnect();
					sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
					System.out.println("connected2: " + sc.isConnected());
					it.remove();
				} else if (key.isValid() && key.isWritable()) {
					write();
					it.remove();
				} else if (key.isValid() && key.isReadable()) {
					System.out.println("readable");
					it.remove();
				}
			}
			try {
				TimeUnit.SECONDS.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws Exception {
		CelerityClientImpl cci = new CelerityClientImpl();
		cci.start();
		System.out.println("write complete!");
		synchronized (cci) {
			cci.wait();
		}
	}

	private void write() throws IOException {
		String s = "1,2,3,4";
		byte[] bs = ObjectUtil.parse(s);
		byte[] length=ObjectUtil.parse(bs.length);
		byte[] value=new byte[bs.length+4];
		System.arraycopy(bs, 0, value, 4, bs.length);
		System.arraycopy(length, 0, value, 0, length.length);
		ByteBuffer buffer = ByteBuffer.wrap(value);
		System.out.println("array: " + Arrays.toString(buffer.array()));
		while (buffer.hasRemaining()) {
			sc.write(buffer);
		}
	}
	
}
